﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using FancyBattles.GameEntities;
using FancyBattles.GameScreen.StateMachine;
using System.Timers;

namespace FancyBattles.GameScreen
{
    class GameplayScreen : GameScreen
    {
        #region Atributes

        private const double SELECT_TIMEOUT = 60999;

        private Dictionary<PlayerIndex, State> screenState = new Dictionary<PlayerIndex,State>();
        private State alteredState;
        private Texture2D stage;
        private List<Texture2D> timerNumbers = new List<Texture2D>();
        private Texture2D timerDecimalNumber;
        private Texture2D timerUnitNumber;
        private Rectangle positionDecimalNumber;
        private Rectangle positionUnitNumber;
        private List<Texture2D> UnitCountNumbers = new List<Texture2D>();
        private Texture2D firstPlayerUnitCount;
        private Texture2D secondPlayerUnitCount;
        private Rectangle firstPlayerUnitCountPos;
        private Rectangle secondPlayerUnitCountPos;
        private double selectTimer;
        public static Boolean isSinglePlayer = false;
        private Texture2D OKUnSelectedRed;
        private Texture2D OKSelectedRed;
        private Texture2D OKUnSelectedBlue;
        private Texture2D OKSelectedBlue;

        #endregion

        #region Properties

        public SpriteFont Font
        {
            get { return ScreenManager.Font; }
        }

        public Dictionary<PlayerIndex, State> ScreenStates
        {
            get { return this.screenState; }
        }

        public State AltState
        {
            get { return this.alteredState; }
            set { this.alteredState = value; }
        }

        #endregion

        #region Creators

        public GameplayScreen()
        {            
            positionDecimalNumber = new Rectangle(598, 36, 46, 57);
            positionUnitNumber = new Rectangle(634, 36, 46, 57);

            firstPlayerUnitCountPos = new Rectangle(99, 116, 24, 33);
            secondPlayerUnitCountPos = new Rectangle(1157, 116, 24, 33);
        }

        #endregion

        #region Methods

        //reset timer and start units movement
        public void OnSelectTimeoutEvent()
        {
            selectTimer = SELECT_TIMEOUT;
            alteredState = new BallRageState(this);
        }

        public void StartGame()
        {
            //for test purposes only
            Gladiator g1 = new Gladiator(new Vector2(350, 340), PlayerIndex.One);
            Gladiator g2 = new Gladiator(new Vector2(350, 460), PlayerIndex.One);
            Archer g3 = new Archer(new Vector2(250, 270), PlayerIndex.One);
            Healer g4 = new Healer(new Vector2(250, 395), PlayerIndex.One);
            Archer g5 = new Archer(new Vector2(250, 520), PlayerIndex.One);

            Gladiator g11 = new Gladiator(new Vector2(900, 340), PlayerIndex.Two);
            Gladiator g12 = new Gladiator(new Vector2(900, 460), PlayerIndex.Two);
            Archer g13 = new Archer(new Vector2(1000, 270), PlayerIndex.Two);
            Healer g14 = new Healer(new Vector2(1000, 395), PlayerIndex.Two);
            Archer g15 = new Archer(new Vector2(1000, 520), PlayerIndex.Two);

            selectTimer = SELECT_TIMEOUT;

            alteredState = new TransitionState(this);
        }

        public override void LoadContent()
        {
            base.LoadContent();

            BouncingBitch.SpriteBatch = SpriteBatch;
            BouncingBitch.Font = Font;
            BouncingBitch.blueHealthBar = ContentManager.Load<Texture2D>("HUD/HEALTHBAR_BLUE");
            BouncingBitch.blueHealthBarFill = ContentManager.Load<Texture2D>("BLUE_HEALTH_BAR");
            BouncingBitch.redHealthBar = ContentManager.Load<Texture2D>("HUD/HEALTHBAR_RED");
            BouncingBitch.redHealthBarFill = ContentManager.Load<Texture2D>("RED_HEALTH_BAR");
            BouncingBitch.blueSelector = ContentManager.Load<Texture2D>("HUD/SELECTOR_P1_BLUE");
            BouncingBitch.redSelector = ContentManager.Load<Texture2D>("HUD/SELECTOR_P2_RED");

            //<internal joke>Temporary fix!</internal joke>
            Gladiator.Idle = ContentManager.Load<Texture2D>("Warrior/WARRIOR_BLUE_01_IDLE");
            Gladiator.Selected = ContentManager.Load<Texture2D>("Warrior/WARRIOR_BLUE_02_SELECTED");
            Gladiator.Confirmed = ContentManager.Load<Texture2D>("Warrior/WARRIOR_BLUE_03_DEFINED");
            Gladiator.Action = ContentManager.Load<Texture2D>("Warrior/WARRIOR_BLUE_04_ACTION");
            Gladiator.Hit = ContentManager.Load<Texture2D>("Warrior/WARRIOR_BLUE_05_HIT");
            Gladiator.Victory = ContentManager.Load<Texture2D>("Warrior/WARRIOR_BLUE_06_VICTORY");
            Gladiator.Death = ContentManager.Load<Texture2D>("Warrior/WARRIOR_BLUE_07_DEATH");
            Gladiator.Stun = ContentManager.Load<Texture2D>("Warrior/WARRIOR_BLUE_08_STUN");
            Gladiator.Heal = ContentManager.Load<Texture2D>("Warrior/WARRIOR_BLUE_09_HEAL");

            Archer.Idle = ContentManager.Load<Texture2D>("Archer/ARCHER_BLUE_01_IDLE");
            Archer.Selected = ContentManager.Load<Texture2D>("Archer/ARCHER_BLUE_02_SELECTED");
            Archer.Confirmed = ContentManager.Load<Texture2D>("Archer/ARCHER_BLUE_03_DEFINED");
            Archer.Action = ContentManager.Load<Texture2D>("Archer/ARCHER_BLUE_04_ACTION");
            Archer.Hit = ContentManager.Load<Texture2D>("Archer/ARCHER_BLUE_05_HIT");
            Archer.Victory = ContentManager.Load<Texture2D>("Archer/ARCHER_BLUE_06_VICTORY");
            Archer.Death = ContentManager.Load<Texture2D>("Archer/ARCHER_BLUE_07_DEATH");
            Archer.Stun = ContentManager.Load<Texture2D>("Archer/ARCHER_BLUE_08_STUN");
            Archer.Heal = ContentManager.Load<Texture2D>("Archer/ARCHER_BLUE_09_HEAL");

            Healer.Idle = ContentManager.Load<Texture2D>("Healer/HEALER_BLUE_01_IDLE");
            Healer.Selected = ContentManager.Load<Texture2D>("Healer/HEALER_BLUE_02_SELECTED");
            Healer.Confirmed = ContentManager.Load<Texture2D>("Healer/HEALER_BLUE_03_DEFINED");
            Healer.Action = ContentManager.Load<Texture2D>("Healer/HEALER_BLUE_04_ACTION");
            Healer.Hit = ContentManager.Load<Texture2D>("Healer/HEALER_BLUE_05_HIT");
            Healer.Victory = ContentManager.Load<Texture2D>("Healer/HEALER_BLUE_06_VICTORY");
            Healer.Death = ContentManager.Load<Texture2D>("Healer/HEALER_BLUE_07_DEATH");
            Healer.Stun = ContentManager.Load<Texture2D>("Healer/HEALER_BLUE_08_STUN");
            Healer.Heal = ContentManager.Load<Texture2D>("Healer/HEALER_BLUE_09_HEAL");

            Archer.BlueGlow = ContentManager.Load<Texture2D>("Archer/ARCHER_GLOW_BLUE");
            Archer.RedGlow = ContentManager.Load<Texture2D>("Archer/ARCHER_GLOW_RED");
            Healer.BlueGlow = ContentManager.Load<Texture2D>("Healer/HEALER_GLOW_BLUE");
            Healer.RedGlow = ContentManager.Load<Texture2D>("Healer/HEALER_GLOW_RED");
            Gladiator.BlueGlow = ContentManager.Load<Texture2D>("Warrior/WARRIOR_GLOW_BLUE");
            Gladiator.RedGlow = ContentManager.Load<Texture2D>("Warrior/WARRIOR_GLOW_RED");

            Arrow.BlueArrow = ContentManager.Load<Texture2D>("Misc/ARCHER_BLUE_ARROW");
            Arrow.RedArrow = ContentManager.Load<Texture2D>("Misc/ARCHER_RED_ARROW");

            DefineShotState.BlueBow = ContentManager.Load<Texture2D>("Misc/ARCHER_BLUE_BOW");
            DefineShotState.RedBow = ContentManager.Load<Texture2D>("Misc/ARCHER_RED_BOW");

            //BouncingBitch.arrows = new Animation(ContentManager.Load<Texture2D>("HUD/MOVEMENTEARROW_BLUE"), 0.1f, true);

            stage = ContentManager.Load<Texture2D>("Stages/CENARIO");
            timerNumbers.Add(ContentManager.Load<Texture2D>("HUD/TIMER_0"));
            timerNumbers.Add(ContentManager.Load<Texture2D>("HUD/TIMER_1"));
            timerNumbers.Add(ContentManager.Load<Texture2D>("HUD/TIMER_2"));
            timerNumbers.Add(ContentManager.Load<Texture2D>("HUD/TIMER_3"));
            timerNumbers.Add(ContentManager.Load<Texture2D>("HUD/TIMER_4"));
            timerNumbers.Add(ContentManager.Load<Texture2D>("HUD/TIMER_5"));
            timerNumbers.Add(ContentManager.Load<Texture2D>("HUD/TIMER_6"));
            timerNumbers.Add(ContentManager.Load<Texture2D>("HUD/TIMER_7"));
            timerNumbers.Add(ContentManager.Load<Texture2D>("HUD/TIMER_8"));
            timerNumbers.Add(ContentManager.Load<Texture2D>("HUD/TIMER_9"));

            UnitCountNumbers.Add(ContentManager.Load<Texture2D>("HUD/UNITS_COUNTER_0"));
            UnitCountNumbers.Add(ContentManager.Load<Texture2D>("HUD/UNITS_COUNTER_1"));
            UnitCountNumbers.Add(ContentManager.Load<Texture2D>("HUD/UNITS_COUNTER_2"));
            UnitCountNumbers.Add(ContentManager.Load<Texture2D>("HUD/UNITS_COUNTER_3"));
            UnitCountNumbers.Add(ContentManager.Load<Texture2D>("HUD/UNITS_COUNTER_4"));
            UnitCountNumbers.Add(ContentManager.Load<Texture2D>("HUD/UNITS_COUNTER_5"));
            UnitCountNumbers.Add(ContentManager.Load<Texture2D>("HUD/UNITS_COUNTER_6"));
            UnitCountNumbers.Add(ContentManager.Load<Texture2D>("HUD/UNITS_COUNTER_7"));
            UnitCountNumbers.Add(ContentManager.Load<Texture2D>("HUD/UNITS_COUNTER_8"));
            UnitCountNumbers.Add(ContentManager.Load<Texture2D>("HUD/UNITS_COUNTER_9"));

            //Separated Arrows
            BouncingBitch.separateArrowsBlue = new List<Texture2D>();
            BouncingBitch.separateArrowsBlue.Add(ContentManager.Load<Texture2D>("HUD/MOVEMENTARROW_BLUE_v2_01"));
            BouncingBitch.separateArrowsBlue.Add(ContentManager.Load<Texture2D>("HUD/MOVEMENTARROW_BLUE_v2_02"));
            BouncingBitch.separateArrowsBlue.Add(ContentManager.Load<Texture2D>("HUD/MOVEMENTARROW_BLUE_v2_03"));
            BouncingBitch.separateArrowsBlue.Add(ContentManager.Load<Texture2D>("HUD/MOVEMENTARROW_BLUE_v2_04"));
            BouncingBitch.separateArrowsBlue.Add(ContentManager.Load<Texture2D>("HUD/MOVEMENTARROW_BLUE_v2_05"));
            BouncingBitch.separateArrowsBlue.Add(ContentManager.Load<Texture2D>("HUD/MOVEMENTARROW_BLUE_v2_06"));
            BouncingBitch.separateArrowsBlue.Add(ContentManager.Load<Texture2D>("HUD/MOVEMENTARROW_BLUE_v2_07"));
            BouncingBitch.separateArrowsBlue.Add(ContentManager.Load<Texture2D>("HUD/MOVEMENTARROW_BLUE_v2_08"));
            BouncingBitch.separateArrowsBlue.Add(ContentManager.Load<Texture2D>("HUD/MOVEMENTARROW_BLUE_v2_09"));
            BouncingBitch.separateArrowsBlue.Add(ContentManager.Load<Texture2D>("HUD/MOVEMENTARROW_BLUE_v2_10"));
            BouncingBitch.separateArrowsBlue.Add(ContentManager.Load<Texture2D>("HUD/MOVEMENTARROW_BLUE_v2_11"));

            BouncingBitch.separateArrowsRed = new List<Texture2D>();
            BouncingBitch.separateArrowsRed.Add(ContentManager.Load<Texture2D>("HUD/MOVEMENTARROW_RED_v2_01"));
            BouncingBitch.separateArrowsRed.Add(ContentManager.Load<Texture2D>("HUD/MOVEMENTARROW_RED_v2_02"));
            BouncingBitch.separateArrowsRed.Add(ContentManager.Load<Texture2D>("HUD/MOVEMENTARROW_RED_v2_03"));
            BouncingBitch.separateArrowsRed.Add(ContentManager.Load<Texture2D>("HUD/MOVEMENTARROW_RED_v2_04"));
            BouncingBitch.separateArrowsRed.Add(ContentManager.Load<Texture2D>("HUD/MOVEMENTARROW_RED_v2_05"));
            BouncingBitch.separateArrowsRed.Add(ContentManager.Load<Texture2D>("HUD/MOVEMENTARROW_RED_v2_06"));
            BouncingBitch.separateArrowsRed.Add(ContentManager.Load<Texture2D>("HUD/MOVEMENTARROW_RED_v2_07"));
            BouncingBitch.separateArrowsRed.Add(ContentManager.Load<Texture2D>("HUD/MOVEMENTARROW_RED_v2_08"));
            BouncingBitch.separateArrowsRed.Add(ContentManager.Load<Texture2D>("HUD/MOVEMENTARROW_RED_v2_09"));
            BouncingBitch.separateArrowsRed.Add(ContentManager.Load<Texture2D>("HUD/MOVEMENTARROW_RED_v2_10"));
            BouncingBitch.separateArrowsRed.Add(ContentManager.Load<Texture2D>("HUD/MOVEMENTARROW_RED_v2_11"));

            //Full Power Arrows
            DefineMoveState.arrowDirectionBlue = ContentManager.Load<Texture2D>("HUD/MOVEMENTARROW_BLUE_FULL");
            DefineMoveState.arrowDirectionRed = ContentManager.Load<Texture2D>("HUD/MOVEMENTARROW_RED_FULL");

            //Animated Arrow
            DefinePowerState.arrowsBlue = new Animation(ContentManager.Load<Texture2D>("HUD/MOVEMENTARROW_BLUE"), 0.1f, true);
            DefinePowerState.arrowsRed = new Animation(ContentManager.Load<Texture2D>("HUD/MOVEMENTARROW_RED"), 0.5f, true);

            //OK
            OKUnSelectedRed = ContentManager.Load<Texture2D>("HUD/OK_RED_1");
            OKSelectedRed = ContentManager.Load<Texture2D>("HUD/OK_RED_2");
            OKUnSelectedBlue = ContentManager.Load<Texture2D>("HUD/OK_BLUE_1");
            OKSelectedBlue = ContentManager.Load<Texture2D>("HUD/OK_BLUE_2");
        }

        public override void UnloadContent()
        {
            base.UnloadContent();
        }

        public override UpdateResponse Update(GameTime gameTime)
        {
            //if units are not moving, update Timer
            if (!alteredState.GetType().Equals(typeof(BallRageState)))
            {
                selectTimer -= gameTime.ElapsedGameTime.TotalMilliseconds;
            }
            if (selectTimer < 1)
            {
                OnSelectTimeoutEvent();
            }

            if (InputHandler.IsPause(PlayerIndex.One) || InputHandler.IsPause(PlayerIndex.Two))
            {
                return UpdateResponse.PAUSE_GAME;
            }
            if (alteredState.GetType().Equals(typeof(ParState)))
            {
                if (screenState[PlayerIndex.One].GetType().Equals(typeof(WaitingState)) && ((screenState[PlayerIndex.Two].GetType().Equals(typeof(WaitingState))) || (IsSinglePlayer())))
                {
                    OnSelectTimeoutEvent();
                    alteredState = new BallRageState(this);
                    foreach (BouncingBitch bitch in BouncingBitch.BitchesList)
                    {
                        bitch.ChangeTexture(BouncingBitch.animationState.Action);
                    }
                    WaitingState.playerOneIsReady = false;
                    WaitingState.playerTwoIsReady = false;
                }
                else
                {
                    screenState[PlayerIndex.One].Update(gameTime);
                    screenState[PlayerIndex.Two].Update(gameTime); 
                }
            }
            else
            {
                alteredState.Update(gameTime);
            }
            if (alteredState.GetType().Equals(typeof(TransitionState)))
            {
                if (((TransitionState)alteredState).IsGameOver)
                {
                    return UpdateResponse.CLOSE_SCREEN;
                }
            }
            return UpdateResponse.KEEP_STATE;
        }

        public bool IsSinglePlayer()
        {
            return isSinglePlayer;
        }

        public override void Draw(GameTime gameTime)
        {
            Rectangle fullscreen = new Rectangle(0, 0, 1280, 720);
            firstPlayerUnitCount = UnitCountNumbers.ElementAt<Texture2D>(BouncingBitch.firstPlayerBitchesCount);
            secondPlayerUnitCount = UnitCountNumbers.ElementAt<Texture2D>(BouncingBitch.secondPlayerBitchesCount);

            SpriteBatch.Begin();

            //Draw Stage
            ScreenManager.SpriteBatch.Draw(stage, fullscreen, Color.White);

            //Draw Timer
            timerDecimalNumber = timerNumbers.ElementAt<Texture2D>((int)selectTimer / 10000);
            timerUnitNumber = timerNumbers.ElementAt<Texture2D>((int)selectTimer / 1000 % 10);

            ScreenManager.SpriteBatch.Draw(timerDecimalNumber, positionDecimalNumber, Color.White);
            ScreenManager.SpriteBatch.Draw(timerUnitNumber, positionUnitNumber, Color.White);

            //Units counter
            ScreenManager.SpriteBatch.Draw(firstPlayerUnitCount, firstPlayerUnitCountPos, Color.White);
            ScreenManager.SpriteBatch.Draw(secondPlayerUnitCount, secondPlayerUnitCountPos, Color.White);

            //OK
            ScreenManager.SpriteBatch.Draw(OKUnSelectedBlue, new Rectangle(517, 46, 64, 39), Color.White);
            ScreenManager.SpriteBatch.Draw(OKUnSelectedRed, new Rectangle(702, 46, 64, 39), Color.White);
            if (WaitingState.playerOneIsReady)
            {
                ScreenManager.SpriteBatch.Draw(OKSelectedBlue, new Rectangle(517, 46, 64, 39), Color.White);
            }
            if (WaitingState.playerTwoIsReady || isSinglePlayer)
            {
                ScreenManager.SpriteBatch.Draw(OKSelectedRed, new Rectangle(702, 46, 64, 39), Color.White);
            }

            if (screenState.ContainsKey(PlayerIndex.One) && screenState.ContainsKey(PlayerIndex.Two))
            {
                screenState[PlayerIndex.One].Draw(gameTime);
                screenState[PlayerIndex.Two].Draw(gameTime);
            }

            alteredState.Draw(gameTime);
            BouncingBitch.DrawBitches();
            Arrow.DrawArrows(SpriteBatch);
            SpriteBatch.End();
            base.Draw(gameTime);
        }

        #endregion
    }
}
